# -*- coding: utf-8 -*-
''' v1 上分接口(将废弃) '''
import json
import random
import time

import requests
from django.conf import settings
from django.http import HttpResponse
from django.template import loader, Context
from django.views.decorators.http import require_GET, require_POST

from common.bankcard import db as bankcard_db
from common.bankcard.model import BANK_DCT, BANKCARD_IMG, STRATEGY_IMG
from common.cache.redis_cache import get_cache_html
from common.mch import handler as mch_handler
from common.mch.db import get_account, get_mch_dct
from common.recharge import db as recharge_db
from common.recharge.model import RECHARGE_ORDER_STATUS
from common.risk import db as risk_db
from common.utils import exceptions as err
from common.utils import track_logging
from common.utils.api import check_params
from common.utils.decorator import response_wrapper
from common.utils.geo import get_city

_LOGGER = track_logging.getLogger(__name__)

BANKCARD_NOT_ACQUIRE = -1


@require_POST
@response_wrapper
def create(request):
    """
    统一下单接口
    PARAMS:
      sdk_version: sdk version code
      service: 服务类型, WECHAT/ALIPAY
      mch_id: 商户号
      out_trade_no: 商户订单号
      body: 商品描述
      total_fee: 总金额
      mch_create_ip: 订单生成的机器ip
      notify_url: 异步通知接口
      sign: 签名
      extra: 附加信息，回调时返回
      chn_type: 通道类型，可选，用户制定通道
    """
    params = request.POST.dict()
    check_params(params, ['sdk_version', 'service', 'mch_id', 'out_trade_no', 'body', 'total_fee', 'mch_create_ip',
                          'notify_url', 'context', 'sign', 'region'], param_type_dct={
        'mch_id': basestring,
        'out_trade_no': basestring,
    })
    sign = params['sign']
    params.pop('sign')
    mch_id = params['mch_id']
    sdk_version = params['sdk_version']
    calculated_sign = mch_handler.generate_sign(mch_id, params)
    if sign != calculated_sign:
        raise err.AuthenticateError('sign error')

    params.update(sign=sign)
    _LOGGER.info('create charge: %s' % params['context'])

    region = get_city(json.loads(params['context'])['user_info'].get('device_ip')) or params['region']

    star, bankcard = bankcard_db.get_bankcard_by_context(mch_id, params['context'], sdk_version=sdk_version)
    if bankcard:
        order = recharge_db.create_order(params['mch_id'], params['out_trade_no'], \
                                         params['user_id'], params['total_fee'], params['context'],
                                         bankcard.account_number, \
                                         params['notify_url'], region, star, sdk_version, bankcard.name)
        order_id = order.id
    else:
        order_id = BANKCARD_NOT_ACQUIRE
    mch_dct = get_mch_dct()
    mch = mch_dct.get(int(mch_id), 'loki')
    info = settings.PAY_GATEWAY_URL[mch] % order_id
    if mch == 'witch' and sdk_version == 'android_v_1_3':
        open_type = 'app_url'
    else:
        open_type = 'sys_url'
    return {
        'charge_info': info,
        'open_type': open_type
    }


@require_POST
@response_wrapper
def fill(request):
    params = request.POST.dict()
    check_params(params,
                 ['random_num', 'pay_type', 'pay_account_num', 'pay_account_bank', 'pay_account_username', 'amount',
                  'order_id', 'sign'])
    sign = params.pop('sign')

    if float(params['amount']) < 48 or float(params['amount']) > 1000000:
        _LOGGER.warning('amount not valid: %s' % params['amount'])
        raise err.ParamError('amount invalid')

    order = recharge_db.get_unfilled_order(params['order_id'])
    if not order:
        raise err.ParamError('invalid order_id')
    sign_params = {
        'random_num': params['random_num'],
        'order_id': params['order_id']
    }
    _LOGGER.info('params in fill is %s' % params)
    calculated_sign = mch_handler.generate_sign(order.mch_id, sign_params)
    if sign != calculated_sign:
        raise err.AuthenticateError('sign error')
    params['status'] = RECHARGE_ORDER_STATUS.WAIT
    order = recharge_db.upsert_order(params, order.id)
    try:
        if not place_order_to_third(order):
            _LOGGER.info('order place to third fail')
    except:
        pass
    return {"success": True}


def place_order_to_third(order):
    bankcard = bankcard_db.get_bankcard_by_num(order.receive_card_num)
    mch = get_account(order.mch_id)
    post_data = {
        "apikey": settings.THIRD_API_KEY,
        "order_id": '_'.join([str(mch.name), str(order.id)]),
        "bank_flag": BANK_DCT[bankcard.bank],
        "card_login_name": bankcard.account_holder,
        "card_number": str(order.receive_card_num),
        "pay_card_number": order.pay_account_num,
        "pay_username": order.pay_account_username,
        "amount": order.amount,
        "create_time": int(time.mktime(order.created_at.timetuple())),
        "comment": "",
    }
    response = requests.post(settings.THIRD_URL + 'authority/system/api/place_order/',
                             headers={'Content-type': 'application/json', 'Accept': 'text/plain'},
                             data=json.dumps(post_data), timeout=5)
    _LOGGER.info('tonglue resp: %s %s' % (response.status_code, response.content))
    response = json.loads(response.content)
    success = response.get('success', None)
    third_id = response.get('id', None)
    if success and third_id:
        order.status = RECHARGE_ORDER_STATUS.THIRD
        order.third_id = str(third_id)
        order.save()
        return True
    else:
        return False


@require_POST
@response_wrapper
def query(request):
    """
    订单查询接口
    """
    params = request.POST.dict()
    check_params(params, ['mch_id',
                          'out_trade_no', 'sign'], param_type_dct={
        'mch_id': basestring,
        'out_trade_no': basestring,
    })
    mch_id = params['mch_id']
    sign = params['sign']
    params.pop('sign')
    mch_id = params['mch_id']
    out_trade_no = params['out_trade_no']
    calculated_sign = mch_handler.generate_sign(mch_id, params)
    if sign != calculated_sign:
        raise err.AuthenticateError('sign error')
    return {}


@require_GET
def get_cache_page(request, cache_id):
    return HttpResponse(get_cache_html(cache_id))


@require_GET
@response_wrapper
def get_gateway_page(request, order_id):
    # case with no bankcard found
    if request.body:
        params = json.loads(request.body)
        disable_bank_img = params.get('disable_bank_img', False)
    else:
        disable_bank_img = False
    if int(order_id) == BANKCARD_NOT_ACQUIRE:
        t = loader.get_template('custom_no_bankcard.html')
        return HttpResponse(t.render())
    # case with bankcard found
    order = recharge_db.get_order(int(order_id))
    if not order or (order.status not in [RECHARGE_ORDER_STATUS.CREATED, RECHARGE_ORDER_STATUS.WAIT,
                                          RECHARGE_ORDER_STATUS.THIRD]):
        return HttpResponse("非法请求")
    card_num = order.receive_card_num
    sdk_version = order.sdk_version
    if risk_db.get_risky_card_by_num(order.pay_account_num, order.mch_id):
        t = loader.get_template('custom_no_bankcard.html')
        return HttpResponse(t.render())
    try:
        user_info = json.loads(order.context).get("user_info")
    except:
        user_info = {}
    bankcard = bankcard_db.get_bankcard_by_num(card_num)
    mch_dct = get_mch_dct()
    mch = mch_dct.get(bankcard.mch_id, 'loki')
    charge_fill_url = settings.PAY_FILL_URL[mch]
    random_num = random.randint(10000000, 99999999)
    params = {
        'random_num': random_num,
        'order_id': order_id
    }
    sign = mch_handler.generate_sign(order.mch_id, params)
    context = Context({
        'bankcard': bankcard,
        'user_id': order.user_id,
        'charge_fill_url': charge_fill_url,
        'random_num': random_num,
        'out_trade_no': order.out_trade_no,
        'order_id': order_id,
        'mch_name': 'xingyuncp' if mch == 'loki' else 'wanhao',
        'is_app_url': 1 if mch == 'witch' and sdk_version == 'android_v_1_3' else 0,
        'sign': sign
    })
    if mch == 'witch':
        t = loader.get_template('custom_bank_witchV3.html')
    else:
        t = loader.get_template('custom_bank_loki.html')
    context['bankcard_img'] = BANKCARD_IMG[bankcard.bank]
    context['strategy_img'] = STRATEGY_IMG

    rendered = t.render(context)
    return HttpResponse(rendered)
